home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************/
- /* qm2patch.c */
- /* */
- /* Purpose: Convert QuickModel scene into Radiosity scene */
- /* */
- /* Origin Programmers: John Buchanan */
- /* Pierre Poulin */
- /* */
- /* Date: 29 November 1989 */
- /* Detail: This is a quick hack. It works if you don't group the */
- /* objects and if you don't use any splines, surface of */
- /* revolution or extrusion. */
- /* */
- /* Programmer: Bernard Kwok */
- /* Date: May 1992 */
- /* Detail: Modified to include surface patches. Changed from */
- /* Optik output to output patches for radiosity program */
- /* Point light sources are not allowed. */
- /* */
- /* Copyright (C) 1992, Bernard Kwok */
- /* All rights reserved. */
- /* Revision 1.0 */
- /* May, 1992 */
- /**********************************************************************/
- #include <stdio.h>
- #include <math.h>
- #include "qm2patch.h"
- extern char *malloc();
-
- float value; /* value read by the parser */
- vector VectorRead = { 0., 0., 0., 1. };
- matrix MatrixRead = {
- 1., 0., 0., 0.,
- 0., 1., 0., 0.,
- 0., 0., 1., 0.,
- 0., 0., 0., 1.
- };
- matrix scaleMatrix;
- matrix rotateMatrix;
- matrix translateMatrix;
- matrix transfMatrix;
- matrix primitiveMatrix;
-
- int isScaleMatrix = FALSE;
- int isRotateMatrix = FALSE;
- int isTranslateMatrix = FALSE;
- int isTransfMatrix = FALSE;
-
- int defaultSurfaceUsed = FALSE;
- Colour colour;
- float diffuse;
- float specular;
-
- int totalid = 0;
- int premesh = 0;
-
- #define TOO_SMALL 1e-10
- float SurfaceParm[2]; /* Surface parameters */
- surface SurfaceRead; /* Surface points */
-
- /**********************************************************************/
- /* Initialize the transformation matrix for an object. */
- /**********************************************************************/
- void Init_Matrix ()
- {
- MxCopy (MatrixRead, transfMatrix);
- isTransfMatrix = TRUE;
- }
-
- /**********************************************************************/
- /* Calculate normal from 3 patch points */
- /**********************************************************************/
- void CalcNormal(p1, p2, p3, n)
- double p1[3];
- double p2[3], p3[3], n[3];
- {
- vector u, v;
- double length;
- int i;
-
- for (i=0;i<3;i++) {
- u[i] = p2[i] - p1[i];
- v[i] = p3[i] - p1[i];
- }
- n[0] = u[1]*v[2] - u[2]*v[1];
- n[1] = u[2]*v[0] - u[0]*v[2];
- n[2] = u[0]*v[1] - u[1]*v[0];
-
- length = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
- length = sqrt(length);
- if (length <= 0.0) {
- fprintf(stderr,"length %g too small, not normalizing\n", length);
- fprintf(stderr,"u = %g,%g,%g; v=%g,%g,%g; n=%g,%g,%g\n", u[0],u[1],u[2],
- v[0],v[1],v[2], n[0],n[1],n[2]);
- exit(1);
- }
- n[0] = n[0] / length;
- n[1] = n[1] / length;
- n[2] = n[2] / length;
-
- if (_ABS(n[0]) < TOO_SMALL) n[0] = 0.0;
- if (_ABS(n[1]) < TOO_SMALL) n[1] = 0.0;
- if (_ABS(n[2]) < TOO_SMALL) n[2] = 0.0;
-
- if (n[0] > 1.0 || n[1] > 1.0 || n[2] > 1.0) {
- fprintf(stderr,"u = %g,%g,%g; v=%g,%g,%g; n=%g,%g,%g; l=%g\n",
- u[0],u[1],u[2], v[0],v[1],v[2], n[0],n[1],n[2], length);
- }
- }
-
- /**********************************************************************/
- /* Compare two vectors to see if equal */
- /**********************************************************************/
- int VComp(v1, v2)
- float v1[5], v2[5];
- {
- register int i;
-
- for(i=0;i<3;i++)
- if (v1[i] != v2[i]) return 0;
- return 1;
- }
-
- /**********************************************************************/
- /* Output patch mesh for object */
- /**********************************************************************/
- void OutputMeshed(namePrimitive, noObject)
- char *namePrimitive; /* name of the primitive */
- int noObject; /* number of the object */
- {
- int i,j,k;
- int patchid = 0;
- int numpatchs = -1;
- int num_vert = -1;
- double patch_vert[4][3];
- double patch_normal[3];
- double tmp[3], tmp1[3], tmp2[3];
-
- if (premesh == 0) {
- printf(" NumMeshes -1\n");
-
- } else if (premesh == 1) {
- printf(" NumMeshes 1\n");
- numpatchs = (int) ((SurfaceParm[0]-1) * (SurfaceParm[1]-1));
- printf(" Mesh mesh%s%d %d {\n", namePrimitive, noObject, numpatchs);
- for (i=0;i<((int)SurfaceParm[0]-1);i++) {
- for (j=0;j<((int)SurfaceParm[1]-1);j++) {
-
- patchid++;
- num_vert = 4;
-
- /* Check for duplicate vertices, illegal patches (<= 2 sides) */
- k = 0;
- if (VComp(SurfaceRead[i][j], SurfaceRead[i+1][j]) ||
- VComp(SurfaceRead[i][j], SurfaceRead[i][j+1]) ||
- VComp(SurfaceRead[i][j], SurfaceRead[i+1][j+1])) {
- num_vert--;
- } else {
- patch_vert[k][0] = SurfaceRead[i][j][0];
- patch_vert[k][1] = SurfaceRead[i][j][1];
- patch_vert[k][2] = SurfaceRead[i][j][2];
- k++;
- }
-
- if (VComp(SurfaceRead[i][j+1], SurfaceRead[i+1][j]) ||
- VComp(SurfaceRead[i][j+1], SurfaceRead[i+1][j+1])) {
- num_vert--;
- } else {
- patch_vert[k][0] = SurfaceRead[i][j+1][0];
- patch_vert[k][1] = SurfaceRead[i][j+1][1];
- patch_vert[k][2] = SurfaceRead[i][j+1][2];
- k++;
- }
-
- if (VComp(SurfaceRead[i+1][j], SurfaceRead[i+1][j+1])) {
- num_vert--;
- } else {
- patch_vert[k][0] = SurfaceRead[i+1][j+1][0];
- patch_vert[k][1] = SurfaceRead[i+1][j+1][1];
- patch_vert[k][2] = SurfaceRead[i+1][j+1][2];
- k++;
- }
-
- patch_vert[k][0] = SurfaceRead[i+1][j][0];
- patch_vert[k][1] = SurfaceRead[i+1][j][1];
- patch_vert[k][2] = SurfaceRead[i+1][j][2];
-
- if (num_vert > 2) {
- /* Calculate and output patch normals */
- tmp[0] = patch_vert[0][0]; tmp[1] = patch_vert[0][1];
- tmp[2] = patch_vert[0][2];
- CalcNormal(patch_vert[0], patch_vert[1], patch_vert[2],
- patch_normal);
- patch_vert[0][0] = tmp[0]; patch_vert[0][1] = tmp[1];
- patch_vert[0][2] = tmp[2];
-
- printf(" Patch norm%d %d {", patchid, num_vert);
- for (k=0;k<num_vert;k++)
- printf(" { %g %g %g }", patch_normal[0], patch_normal[1],
- patch_normal[2]);
- printf(" }\n");
-
-
- /* Output patch vertices */
- printf(" Patch vert%d %d {", patchid, num_vert);
- for (k=0;k<num_vert;k++) {
- if (_ABS(patch_vert[k][0]) < TOO_SMALL) patch_vert[k][0] = 0.0;
- if (_ABS(patch_vert[k][1]) < TOO_SMALL) patch_vert[k][1] = 0.0;
- if (_ABS(patch_vert[k][2]) < TOO_SMALL) patch_vert[k][2] = 0.0;
- printf(" { %g %g %g }", patch_vert[k][0], patch_vert[k][1],
- patch_vert[k][2]);
- }
- printf(" }\n");
- }
- }
- }
- printf(" }\n");
- }
- }
-
- /**********************************************************************/
- /* Compute the transformation matrix and output the object in */
- /* radiosity format */
- /**********************************************************************/
- void OutputObject (namePrimitive, noObject)
- char *namePrimitive; /* name of the primitive */
- int noObject; /* number of the object */
- {
- matrix resultingMatrix;
-
- MxIdentity (resultingMatrix);
- MxMultiply (resultingMatrix, primitiveMatrix, resultingMatrix);
-
- if (isScaleMatrix) {
- MxMultiply (resultingMatrix, scaleMatrix, resultingMatrix);
- isScaleMatrix = FALSE;
- }
- if (isRotateMatrix) {
- MxMultiply (resultingMatrix, rotateMatrix, resultingMatrix);
- isRotateMatrix = FALSE;
- }
- if (isTranslateMatrix) {
- MxMultiply (resultingMatrix, translateMatrix, resultingMatrix);
- isTranslateMatrix = FALSE;
- }
- if (isTransfMatrix) {
- MxMultiply (resultingMatrix, transfMatrix, resultingMatrix);
- isTransfMatrix = FALSE;
- }
-
- /* Output header definition */
- printf("\nObject %s%d %s {\n", namePrimitive, noObject, namePrimitive);
-
- /* Output matrix column order */
- printf(" OWMatrix mat%s%d { %g %g %g %g %g %g %g %g %g %g %g %g }\n",
- namePrimitive, noObject,
- resultingMatrix[0][0], resultingMatrix[0][1], resultingMatrix[0][2],
- resultingMatrix[1][0], resultingMatrix[1][1], resultingMatrix[1][2],
- resultingMatrix[2][0], resultingMatrix[2][1], resultingMatrix[2][2],
- resultingMatrix[3][0], resultingMatrix[3][1], resultingMatrix[3][2]);
-
- /* Output surface properties. Reflectance assumed == colour */
- if (diffuse != 0. || specular != 0.) {
- printf(" Prop prop%s%d { E{ 0.0 0.0 0.0 } p{ %g %g %g } Kd{ %g } Ks{ %g } }\n",
- namePrimitive, noObject, colour.red, colour.green,
- colour.blue, diffuse, specular);
- colour.red = colour.green = colour.blue = 0.;
- diffuse = specular = 0.;
-
- } else if (colour.red != 0. || colour.green != 0. || colour.blue != 0.) {
- printf(" Prop prop%s%d { E{ 0.0 0.0 0.0 } p{ %g %g %g } ",
- namePrimitive, noObject, colour.red, colour.green, colour.blue);
- printf("Kd{ 1.0 } Ks{ 0.0 } \n");
- colour.red = colour.green = colour.blue = 0.;
-
- } else { /* Use default properties for object == pure diffuse */
- printf(" Prop prop%s%d { E{ 0.0 0.0 0.0 } ",
- namePrimitive, noObject);
- printf("p{ 0.0 0.0 0.0 } Kd{ 1.0 } Ks{ 0.0 } \n");
- }
-
- /* Output meshed object patches */
- OutputMeshed(namePrimitive, noObject);
-
- /* End delimiter */
- printf("}\n");
-
- totalid++;
- }
-
- /**********************************************************************/
- /* The object is a polygonal mesh */
- /**********************************************************************/
- void Surface()
- {
- int i,j;
- static int surfaceid = 0;
- char *name = "mesh";
- matrix tempMatrix;
-
- if ((SurfaceParm[0] != 1) && (SurfaceParm[1] != 1)) {
- MxIdentity (primitiveMatrix);
- premesh = 1;
- surfaceid++;
- OutputObject (name, surfaceid);
- }
- }
-
- /**********************************************************************/
- /* The object is a cone */
- /**********************************************************************/
- void Cone()
- {
- static int coneid = 0;
- char *name = "cone";
- matrix tempMatrix;
-
- MxIdentity (primitiveMatrix);
- MxScale (primitiveMatrix, 0.5, 0.5, 0.5);
- primitiveMatrix[3][2] = -0.5;
- coneid++;
- premesh = 0;
- OutputObject (name, coneid);
- }
-
- /**********************************************************************/
- /* The object is a cube */
- /**********************************************************************/
- void Cube ()
- {
- static int cubeid = 0;
- char *name = "cube";
-
- MxIdentity (primitiveMatrix);
- MxScale(primitiveMatrix, 0.5, 0.5, 0.5);
- cubeid++;
- premesh = 0;
- OutputObject (name, cubeid);
- }
-
- /**********************************************************************/
- /* The object is a cylinder */
- /**********************************************************************/
- void Cylinder()
- {
- static int cylinderid = 0;
- char *name = "cylinder";
-
- MxIdentity (primitiveMatrix);
- MxScale(primitiveMatrix, 0.5, 0.5, 0.5);
- cylinderid++;
- premesh = 0;
- OutputObject (name, cylinderid);
- }
-
- /**********************************************************************/
- /* The object is a sphere */
- /**********************************************************************/
- void Sphere()
- {
- static int sphereid = 0;
- char *name = "sphere";
-
- MxIdentity (primitiveMatrix);
- MxScale(primitiveMatrix, 0.5, 0.5, 0.5);
- sphereid++;
- premesh = 0;
- OutputObject (name, sphereid);
- }
-
- /*
- * The object is a point light source (not used)
- */
- void Light()
- { }
-
- void OptikLight ()
- {
- static int lightid = 0;
- matrix resultingMatrix;
-
- MxIdentity (resultingMatrix);
-
- if (isRotateMatrix || isScaleMatrix)
- {
- printf ("\n /* Rotation or scale of light issued, ");
- printf ("not handled. */\n\n");
- isRotateMatrix = isScaleMatrix = FALSE;
- }
-
- if (isTranslateMatrix)
- {
- MxMultiply (resultingMatrix, translateMatrix, resultingMatrix);
- isTranslateMatrix = FALSE;
- }
-
- if (isTransfMatrix)
- {
- MxMultiply (resultingMatrix, transfMatrix, resultingMatrix);
- isTransfMatrix = FALSE;
- }
-
- printf ("add light light%d point ", lightid);
-
- if (resultingMatrix[3][0] != 0. || resultingMatrix[3][1] != 0. ||
- resultingMatrix[3][2] != 0.)
- {
- printf ("%g %g %g ", resultingMatrix[3][0],
- resultingMatrix[3][1], resultingMatrix[3][2]);
- }
- else
- if (colour.red != 0. || colour.green != 0. || colour.blue != 0.)
- /* default position of the light at the origin */
- printf ("0 0 0 ");
-
- if (colour.red != 0. || colour.green != 0. || colour.blue != 0.)
- {
- printf ("%g %g %g ", colour.red, colour.green, colour.blue);
- colour.red = colour.green = colour.blue = 0.;
- }
-
- printf ("\n");
-
- if (diffuse != 0. || specular != 0.)
- {
- printf ("\n /* Diffusion or specularity of light issued, ");
- printf ("not handled. */\n\n");
- diffuse = specular = 0.;
- }
- }
-
- /**********************************************************************/
- /* Scale the object */
- /**********************************************************************/
- void Scale ()
- {
- MxIdentity (scaleMatrix);
- MxScale (scaleMatrix, VectorRead[0], VectorRead[1], VectorRead[2]);
- isScaleMatrix = TRUE;
- }
-
- /**********************************************************************/
- /* Translate the object */
- /**********************************************************************/
- void Translate ()
- {
- MxIdentity (translateMatrix);
- MxTranslate (translateMatrix, VectorRead[0], VectorRead[1],
- VectorRead[2]);
- isTranslateMatrix = TRUE;
- }
-
- /**********************************************************************/
- /* Rotate the object */
- /**********************************************************************/
- void Rotate ()
- {
- matrix tempMatrix;
-
- MxIdentity (rotateMatrix);
- if (VectorRead[0] != 0.)
- MxRotateD (rotateMatrix, VectorRead[0], 'x');
- if (VectorRead[1] != 0.) {
- MxIdentity (tempMatrix);
- MxRotateD (tempMatrix, VectorRead[1], 'y');
- MxMultiply (rotateMatrix, tempMatrix, rotateMatrix);
- }
- if (VectorRead[2] != 0.) {
- MxIdentity (tempMatrix);
- MxRotateD (tempMatrix, VectorRead[2], 'z');
- MxMultiply (rotateMatrix, tempMatrix, rotateMatrix);
- }
- isRotateMatrix = TRUE;
- }
-
- /**********************************************************************/
- /* Specify the emission of the surface */
- /**********************************************************************/
- void SurfColour ()
- {
- colour.red = VectorRead[0];
- colour.green = VectorRead[1];
- colour.blue = VectorRead[2];
- }
-
- /**********************************************************************/
- /* Specify the diffuse coefficient of the surface */
- /**********************************************************************/
- void Diffusion ()
- {
- diffuse = value;
- }
-
- /**********************************************************************/
- /* Specify the specular coefficient of the surface */
- /**********************************************************************/
- void Specularity ()
- {
- specular = value;
- }
-